package com.example.serverdemo.bean.json.device;

import cn.hutool.core.convert.Convert;
import com.example.serverdemo.utils.crcutls.CRC16Tool;
import com.example.serverdemo.utils.crcutls.CRCUtil;
import com.example.serverdemo.utils.crcutls.LightControllerCRCUtil;
import com.example.serverdemo.utils.log.PrintLogUtil;
import com.example.serverdemo.utils.stringutils.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;

public class LightControllerParameterBean{

    private int relayCount;
    private int dmxCount;
    private int relayDataSize;
    private boolean isOpenFan;
    private int airControllerSwitch;
    private boolean isOpenAirCondition;
    private int lightProtocol;
    private int lightMode;
    private int fanChannel;
    private int highFanChannel;
    private int middleFanChannel;
    private int lowFanChannel;
    private int openAirConditionChannel;
    private int closeAirConditionChannel;
    private int placeHolderOne;
    private int placeHolderTwo;
    private boolean[][] sceneData;
    private int[] dmxData;

    public static LightControllerParameterBean build(byte[] data){
        LightControllerParameterBean bean = null;
        try {
            int point = 0;
            bean = new LightControllerParameterBean();
            bean.relayCount = Convert.byteToUnsignedInt(data[point++]);
            bean.dmxCount = Convert.byteToUnsignedInt(data[point++]);
            bean.relayDataSize = Convert.byteToUnsignedInt(data[point++]);
            bean.isOpenFan = Convert.byteToUnsignedInt(data[point++]) == 1;
            bean.airControllerSwitch = Convert.byteToUnsignedInt(data[point++]);
            bean.isOpenAirCondition = Convert.byteToUnsignedInt(data[point++]) == 1;
            bean.lightProtocol = Convert.byteToUnsignedInt(data[point++]);
            bean.lightMode = Convert.byteToUnsignedInt(data[point++]);
            bean.fanChannel = Convert.byteToUnsignedInt(data[point++]);
            bean.highFanChannel = Convert.byteToUnsignedInt(data[point++]);
            bean.middleFanChannel = Convert.byteToUnsignedInt(data[point++]);
            bean.lowFanChannel = Convert.byteToUnsignedInt(data[point++]);
            bean.openAirConditionChannel = Convert.byteToUnsignedInt(data[point++]);
            bean.closeAirConditionChannel = Convert.byteToUnsignedInt(data[point++]);
            bean.placeHolderOne = Convert.byteToUnsignedInt(data[point++]);
            bean.placeHolderTwo = Convert.byteToUnsignedInt(data[point++]);
            bean.sceneData = new boolean[17][bean.relayCount];
            for (int relayIndex = 0;relayIndex < bean.relayDataSize;relayIndex++){
                for (int frameIndex = 0;frameIndex < 17;frameIndex++){
                    String binaryStr = Integer.toBinaryString(1 << 8 | Convert.byteToUnsignedInt(data[point++])).substring(1);
                    Character[] charArray = Convert.toCharArray(binaryStr);
                    for (int dataIndex = 0;dataIndex < 8 && relayIndex * 8 + dataIndex < bean.relayCount;dataIndex++){
                        bean.sceneData[frameIndex][8 * relayIndex + dataIndex] = charArray[7- dataIndex].equals('1');
                    }
                }
            }
            if (bean.dmxCount != 0){
                bean.dmxData = new int[bean.dmxCount];
                for (int dmxIndex = 0;dmxIndex < bean.dmxCount;dmxIndex++){
                    bean.dmxData[dmxIndex] = data[point++];
                }
            }
        }catch (Exception e){
            PrintLogUtil.printError(LightControllerParameterBean.class.getName(),e);
        }
        return bean;
    }
    public byte[] toHexData(){
        try {
            ArrayList<Byte> array = new ArrayList<>();
            array.add(Convert.intToByte(this.relayCount));
            array.add(Convert.intToByte(this.dmxCount));
            array.add(Convert.intToByte(this.relayDataSize));
            array.add(Convert.intToByte(this.isOpenFan ? 1:0));
            array.add(Convert.intToByte(this.airControllerSwitch));
            array.add(Convert.intToByte(this.isOpenAirCondition ? 1:0));
            array.add(Convert.intToByte(this.lightProtocol));
            array.add(Convert.intToByte(this.lightMode));
            array.add(Convert.intToByte(this.fanChannel));
            array.add(Convert.intToByte(this.highFanChannel));
            array.add(Convert.intToByte(this.middleFanChannel));
            array.add(Convert.intToByte(this.lowFanChannel));
            array.add(Convert.intToByte(this.openAirConditionChannel));
            array.add(Convert.intToByte(this.closeAirConditionChannel));
            array.add(Convert.intToByte(this.placeHolderOne));
            array.add(Convert.intToByte(this.placeHolderTwo));
            for (int relayIndex = 0;relayIndex < this.relayDataSize;relayIndex++){
                for (int frameIndex = 0;frameIndex < 17;frameIndex++){
                    String binaryStr = "";
                    for (int dataIndex = 0;dataIndex < 8 && relayIndex * 8 + dataIndex < this.relayCount;dataIndex++){
                        binaryStr = (this.sceneData[frameIndex][relayIndex * 8 + dataIndex] ? "1":"0") + binaryStr + "";
                    }
                    array.add(Convert.intToByte(Integer.valueOf(binaryStr,2)));
                }
            }
            if (this.dmxData != null){
                for (int dataIndex = 0;dataIndex < this.dmxData.length;dataIndex++){
                    array.add(Convert.intToByte(this.dmxData[dataIndex]));
                }
            }
            byte[] buff = LightControllerCRCUtil.getCrc(Convert.toPrimitiveByteArray(array));
            array.add(buff[3]);
            array.add(buff[2]);
            return Convert.toPrimitiveByteArray(array);
        }catch (Exception e){
            PrintLogUtil.printError(LightControllerParameterBean.class.getName(),e);
        }
        return null;
    }

    public int getRelayCount() {
        return relayCount;
    }

    public void setRelayCount(int relayCount) {
        this.relayCount = relayCount;
    }

    public int getDmxCount() {
        return dmxCount;
    }

    public void setDmxCount(int dmxCount) {
        this.dmxCount = dmxCount;
    }

    public int getRelayDataSize() {
        return relayDataSize;
    }

    public void setRelayDataSize(int relayDataSize) {
        this.relayDataSize = relayDataSize;
    }

    public boolean isOpenFan() {
        return isOpenFan;
    }

    public void setOpenFan(boolean openFan) {
        isOpenFan = openFan;
    }

    public int getAirControllerSwitch() {
        return airControllerSwitch;
    }

    public void setAirControllerSwitch(int airControllerSwitch) {
        this.airControllerSwitch = airControllerSwitch;
    }

    public boolean isOpenAirCondition() {
        return isOpenAirCondition;
    }

    public void setOpenAirCondition(boolean openAirCondition) {
        isOpenAirCondition = openAirCondition;
    }

    public int getLightProtocol() {
        return lightProtocol;
    }

    public void setLightProtocol(int lightProtocol) {
        this.lightProtocol = lightProtocol;
    }

    public int getLightMode() {
        return lightMode;
    }

    public void setLightMode(int lightMode) {
        this.lightMode = lightMode;
    }

    public int getFanChannel() {
        return fanChannel;
    }

    public void setFanChannel(int fanChannel) {
        this.fanChannel = fanChannel;
    }

    public int getHighFanChannel() {
        return highFanChannel;
    }

    public void setHighFanChannel(int highFanChannel) {
        this.highFanChannel = highFanChannel;
    }

    public int getMiddleFanChannel() {
        return middleFanChannel;
    }

    public void setMiddleFanChannel(int middleFanChannel) {
        this.middleFanChannel = middleFanChannel;
    }

    public int getLowFanChannel() {
        return lowFanChannel;
    }

    public void setLowFanChannel(int lowFanChannel) {
        this.lowFanChannel = lowFanChannel;
    }

    public int getOpenAirConditionChannel() {
        return openAirConditionChannel;
    }

    public void setOpenAirConditionChannel(int openAirConditionChannel) {
        this.openAirConditionChannel = openAirConditionChannel;
    }

    public int getCloseAirConditionChannel() {
        return closeAirConditionChannel;
    }

    public void setCloseAirConditionChannel(int closeAirConditionChannel) {
        this.closeAirConditionChannel = closeAirConditionChannel;
    }

    public int getPlaceHolderOne() {
        return placeHolderOne;
    }

    public void setPlaceHolderOne(int placeHolderOne) {
        this.placeHolderOne = placeHolderOne;
    }

    public int getPlaceHolderTwo() {
        return placeHolderTwo;
    }

    public void setPlaceHolderTwo(int placeHolderTwo) {
        this.placeHolderTwo = placeHolderTwo;
    }

    public boolean[][] getSceneData() {
        return sceneData;
    }

    public void setSceneData(boolean[][] sceneData) {
        this.sceneData = sceneData;
    }

    public int[] getDmxData() {
        return dmxData;
    }

    public void setDmxData(int[] dmxData) {
        this.dmxData = dmxData;
    }
}
